﻿package {
	import flash.display.BlendMode;
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import idv.cjcat.pyronova.display.PyroCanvas;
	import idv.cjcat.pyronova.display.PyroLayer;
	import idv.cjcat.pyronova.nodes.BitmapDataNode;
	import idv.cjcat.pyronova.nodes.BlurNode;
	import idv.cjcat.pyronova.nodes.DisplacementNode;
	import idv.cjcat.pyronova.nodes.DisplayObjectNode;
	import idv.cjcat.pyronova.nodes.PerlinNoiseNode;
	import idv.cjcat.pyronova.nodes.RedrawNode;
	import idv.cjcat.pyronova.transform.color.ExposureTransform;
	import idv.cjcat.pyronova.transform.MatrixTransform;
	import idv.cjcat.pyronova.utils.PyroMath;
	import idv.cjcat.pyronova.xml.XMLBuilder;
	
	public class Main extends Sprite {
		
		private var bmpdNode:BitmapDataNode;
		private var perlinNode:PerlinNoiseNode;
		private var displacementNode:DisplacementNode;
		private var blurNode:BlurNode;
		private var lightenNode:RedrawNode;
		
		private var perlinOffset:Point = new Point();
		
		private var canvas:PyroCanvas;
		private var layer1:PyroLayer;
		private var layer2:PyroLayer;
		
		public function Main():void {
			stage.scaleMode = StageScaleMode.NO_SCALE;
			
			//create nodes
			bmpdNode = new BitmapDataNode(new BIB(300, 300));
			perlinNode = new PerlinNoiseNode(6, 6, 1, 0, true, true, 3);
			displacementNode = new DisplacementNode(bmpdNode, perlinNode);
			blurNode = new BlurNode(displacementNode, 20, 20, 2);
			lightenNode = new RedrawNode(blurNode);
			
			//setup nodes
			bmpdNode.setSize(300, 300);
			bmpdNode.render(); //only needed once
			perlinNode.setSize(100, 100);
			perlinNode.offsets = [perlinOffset];
			displacementNode.setSize(300, 300);
			displacementNode.mapTransform = new MatrixTransform(3, 0, 0, 3);
			blurNode.setSize(150, 150);
			blurNode.inputTransform = new MatrixTransform(0.5, 0, 0, 0.5);
			lightenNode.setSize(150, 150);
			lightenNode.inputColorTransform = new ExposureTransform(1.3);
			
			//create canvas
			canvas = new PyroCanvas();
			
			//setup canvas
			canvas.renderList = [perlinNode, displacementNode, blurNode, lightenNode]; //exclude bmpNode
			
			//create layers
			layer1 = new PyroLayer(displacementNode);
			layer2 = new PyroLayer(lightenNode);
			
			//setup layers
			layer2.blendMode = BlendMode.ADD;
			layer2.scaleX = layer2.scaleY = 2;
			
			//add layers to canvas
			canvas.addLayer(layer1);
			canvas.addLayer(layer2);
			
			//add canvas to stage
			addChildAt(canvas, 0);
			
			//first render
			canvas.render();
			blurNode.render();
			
			//add listeners
			stage.addEventListener(Event.ENTER_FRAME, mainLoop);
			bmp_btn.addEventListener(MouseEvent.CLICK, toggleBmp);
			glow_btn.addEventListener(MouseEvent.CLICK, toggleGlow);
			
			trace(XMLBuilder.buildXML(canvas).toXMLString());
		}
		
		private function mainLoop(e:Event):void {
			perlinOffset.x++;
			displacementNode.scaleX = displacementNode.scaleY = PyroMath.clamp(0.1 * mouseX, 0, 30);
			layer2.alpha = PyroMath.clamp(mouseY / 300, 0, 1);
			
			canvas.render();
		}
		
		private function toggleBmp(e:MouseEvent):void {
			layer1.visible = !layer1.visible;
			if (layer1.visible) {
				bmp_btn.label = "Hide Bitmap";
			} else {
				bmp_btn.label = "Show Bitmap";
			}
		}
		
		private function toggleGlow(e:MouseEvent):void {
			layer2.visible = !layer2.visible;
			if (layer2.visible) {
				glow_btn.label = "Hide Glow";
				canvas.renderList = [perlinNode, displacementNode, blurNode, lightenNode];
			} else {
				glow_btn.label = "Show Glow";
				canvas.renderList = [perlinNode, displacementNode];
			}
		}
	}
}